#include <iostream>
#include <mysql/mysql.h>
#include <unistd.h>
#include <string>
using namespace std;

const string host = "106.54.51.147";
const string user = "cr";
const string passwd = "20040712";
const string db = "conndb";
const unsigned int port = 3306;

int main()
{
    // 1.初始化
    // 用于存储有关数据库连接的各种信息，如连接状态、错误信息、查询结果等
    MYSQL *msq = mysql_init(nullptr);
    if (nullptr == msq)
    {
        cerr << "mysql_init failed..." << endl;
        return -1;
    }
    // 1.1设置默认字符集
    mysql_set_character_set(msq, "utf8");

    // 2.连接数据库
    if (nullptr == mysql_real_connect(msq, host.c_str(), user.c_str(), passwd.c_str(),
                                      db.c_str(), port, nullptr, 0))
    {
        cerr << "mysql_real_connect failed..." << endl;
        return -1;
    }
    cout << "连接数据库成功..." << endl;

    // 3.进行相关数据库操作
    // 3.1建test表
    string create_sql = "create table if not exists test(\
        id bigint unsigned primary key auto_increment,\
        name varchar(20) not null,\
        age tinyint unsigned not null\
    );";
    if (0 != mysql_query(msq, create_sql.c_str()))
    {
        cerr << "mysql_query create failed..." << endl;
        return -1;
    }
    cout << "建表成功..." << endl;

    // 3.2插入数据
    // string insert_sql = "insert into test value(3,'lcy','20')";
    // if (0 != mysql_query(msq, insert_sql.c_str()))
    // {
    //     cerr << "mysql_query insert failed..." << endl;
    //     return -1;
    // }
    // cout << "数据插入成功..." << endl;

    // 3.3查看数据
    string select_sql = "select * from test";
    if (0 != mysql_query(msq, select_sql.c_str()))
    {
        cerr << "mysql_query select failed..." << endl;
        return -1;
    }
    else // 处理查询结果
    {
        // 3.31转储获取查询数据+属性
        MYSQL_RES *res = mysql_store_result(msq);
        if (nullptr == res)
        {
            cerr << "mysql_store_result failed..." << endl;
            return -1;
        }
        // 3.32获取数据行列数
        uint64_t rows = mysql_num_rows(res);
        uint64_t cols = mysql_num_fields(res);

        // 3.34获取res中列属性的结构体对象(同时还有表、库等信息字段)
        MYSQL_FIELD *field = mysql_fetch_fields(res);
        for (int i = 0; i < cols; i++) // 遍历每一列
        {
            cout << field[i].name << "\t";
        }
        cout << endl;

        for (int i = 0; i < rows; i++) // 遍历每一行
        {
            // 3.34获取res中指向每一行表数据的成员指针(char**)
            MYSQL_ROW lines = mysql_fetch_row(res); // 每获取一次就指向下一行
            for (int j = 0; j < cols; j++)          // 遍历每一列
            {
                cout << lines[j] << '\t';
            }
            cout << endl;
        }
        // 3.35释放结果集
        mysql_free_result(res);
    }

    // 4.关闭数据库连接
    mysql_close(msq);
    return 0;
}